<!DOCTYPE html>
            
<HTML>
<HEAD>
<meta name="booktitle" content="Developing Applications With Objective Caml" >
 <meta charset="ISO-8859-1"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<META name="GENERATOR" content="hevea 1.05-7 of 2000-02-24">
<META NAME="Author" CONTENT="Christian.Queinnec@lip6.fr">
<LINK rel=stylesheet type="text/css" href="videoc-ocda.css">
<script language="JavaScript" src="videoc.js"><!--
//--></script>
<TITLE>
 Communication between C and Objective CAML
</TITLE>
</HEAD>
<BODY class="regularBody">
<A HREF="book-ora113.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora115.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2> Communication between C and Objective CAML</H2>
<A NAME="@concepts254"></A>
Communication between parts of a program written in C and in
Objective CAML is accomplished by creating an executable (or a new toplevel
interpreter) containing both parts. These parts can be separately compiled.
It is therefore the responsibility of the linking
phase<A NAME="text29" HREF="book-ora122.html#note29"><SUP><FONT SIZE=2>2</FONT></SUP></A> to establish the connection
between Objective CAML function names and C function names, and to create
the final executable. To this end, the Objective CAML part of the program
contains external declarations describing this connection.<BR>
<BR>
Figure <A HREF="book-ora114.html#fig-com1-C">12.1</A> shows a sample program composed of a C part
and an Objective CAML part.
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<IMG SRC="book-ora042.gif">
</DIV>
<BR>
<DIV ALIGN=center>Figure 12.1: Communication between Objective CAML and C.</DIV><BR>

<A NAME="fig-com1-C"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>
Each part comprises code (function definitions and toplevel
expressions for Objective CAML) and a memory area for dynamic allocation.
Calling the function <TT>f</TT> with three Objective CAML integer arguments
triggers a call to the C function <TT>f_c</TT>. The body of the C
function converts the three Objective CAML integers to C integers, computes
their sum, and returns the result converted to an Objective CAML integer.<BR>
<BR>
We now introduce the basic mechanisms for interfacing C with Objective CAML:
external declarations, calling conventions for C functions invoked
from Objective CAML, and linking options. Then, we show an example using
input-output.<BR>
<BR>
<A NAME="toc147"></A>
<H3> External declarations</H3>
<A NAME="@concepts255"></A>
<A NAME="@concepts256"></A>
<A NAME="@fonctions362"></A>
External function declarations in Objective CAML associate a C function
definition with an Objective CAML name, while giving the type of the latter.<BR>
<BR>
The syntax is as follows:


<H3> Syntax </H3> <HR>


<B>external</B> <I>caml_name</I> <B>:</B> <I>type</I> <B>=</B> 
<B>"</B><I>C_name</I><B>"</B>



<HR>


This declaration indicates that calling the function <I>caml_name</I>
from Objective CAML code performs a call to the C function <I>C_name</I>
with the given arguments. Thus, the example in figure
<A HREF="book-ora114.html#fig-com1-C">12.1</A> declares the function <TT>f</TT> as the Objective CAML
equivalent of the C function <TT>f_c</TT>.<BR>
<BR>
An external function can be declared in an interface
(i.e., in an <TT>.mli</TT> file) either as an external or as a
regular value:


<H3> Syntax </H3> <HR>

 
<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=left NOWRAP><B>external</B> <I>caml_name</I> <B>:</B> <I>type</I> <B>=</B> 
<B>"</B><I>C_name</I><B>"</B></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><B>val</B> <I>caml_name</I> <B>:</B> <I>type</I></TD>
</TR></TABLE>
 


<HR>


In the latter case, calls to the C function first go through the
general function application mechanism of Objective CAML. This is slightly
less efficient, but hides the implementation of the function as a C
function.<BR>
<BR>
<A NAME="toc148"></A>
<H3> Declaration of the C functions</H3>
<A NAME="@fonctions363"></A>
<A NAME="@concepts257"></A>
C functions intended to be called from Objective CAML must have the same
number of arguments as described in their external declarations.
These arguments have type <TT>value</TT>, which is the C type for
Objective CAML values. Since those values have uniform representations
(<A HREF="index.html#chap-GC">9</A>), a single C type suffices to encode all
Objective CAML values. On page <A HREF="book-ora115.html#sec-explor-IC">??</A>, we will present the
facilities for encoding and decoding values, and illustrate them by a
function that explores the representations of Objective CAML values.<BR>
<BR>
The example in figure <A HREF="book-ora114.html#fig-com1-C">12.1</A> respects the constraints
mentioned above. The function <TT>f_c</TT>, associated with an
Objective CAML function of type <I>int -&gt; int -&gt; int -&gt; int</I>, is indeed
a function with three parameters of type <TT>value</TT> returning a
result of type <TT>value</TT>.<BR>
<BR>
The Objective CAML bytecode interpreter evaluates calls to external
functions differently, depending on the number of arguments<A NAME="text30" HREF="book-ora122.html#note30"><SUP><FONT SIZE=2>3</FONT></SUP></A>.
If the number of arguments is less than or equal to five, the
arguments are passed directly to the C function. If the number of
arguments is greater than five, the C function's first parameter
will get an array containing all of the arguments, and the C function's
second parameter will get the number of arguments. These two cases must therefore be
distinguished for external C functions that can be called from the
bytecode interpreter. On the other hand, the Objective CAML native-code
compiler always calls external functions by passing all the
arguments directly, as function parameters.<BR>
<BR>

<H4> External functions with more than five arguments</H4>
For external functions with more than five arguments, the programmer
must provide two C functions: one for bytecode and the other for
native-code. The syntax of external declarations allows the declaration of
one Objective CAML function associated with two C functions:


<H3> Syntax </H3> <HR>


<B>external</B> <I>caml_name</I> <B>:</B> <I>type</I> <B>=</B> 
<B>"</B><I>C_name_bytecode</I><B>"</B> 
<B>"</B><I>C_name_native</I><B>"</B>



<HR>


The function <I>C_name_bytecode</I> takes two parameters: an array of
values of type <TT>value</TT> (i.e. a C pointer of type <TT>value*</TT>) and an integer giving the number of elements in this array.<BR>
<BR>

<H4> Example</H4>
The following C program defines two functions for adding together six
integers: <TT>plus_native</TT>, callable from native code,
and <TT>plus_bytecode</TT>, callable from the bytecode compiler. The C code
must include the file <TT>mlvalues.h</TT> containing the definitions 
of C types, Objective CAML values, and conversion macros.<BR>
<BR>


<PRE>
<CODE>#include &lt;stdio.h&gt;</CODE><BR><CODE>#include &lt;caml/mlvalues.h&gt;</CODE><BR><BR><CODE>value plus_native (value x1,value x2,value x3,value x4,value x5,value x6)</CODE><BR><CODE>{</CODE><BR><CODE>  printf("&lt;&lt; NATIVE PLUS &gt;&gt;\n") ; fflush(stdout) ;</CODE><BR><CODE>  return Val_long ( Long_val(x1) + Long_val(x2) + Long_val(x3)</CODE><BR><CODE>                  + Long_val(x4) + Long_val(x5) + Long_val(x6)) ;</CODE><BR><CODE>}</CODE><BR><BR><CODE>value plus_bytecode (value * tab_val, int num_val)</CODE><BR><CODE>{</CODE><BR><CODE>  int i;</CODE><BR><CODE>  long res;</CODE><BR><CODE>  printf("&lt;&lt; BYTECODED PLUS &gt;&gt; : ") ; fflush(stdout) ;</CODE><BR><CODE>  for (i=0,res=0;i&lt;num_val;i++) res += Long_val(tab_val[i]) ;</CODE><BR><CODE>  return Val_long(res) ;</CODE><BR><CODE>}</CODE><BR><BR>

</PRE>

The following Objective CAML program <TT>exOCAML.ml</TT> calls these two C
functions.


<PRE><BR><B>external</B><CODE> </CODE>plus<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int<CODE> </CODE>-&gt;<CODE> </CODE>int<CODE> </CODE>-&gt;<CODE> </CODE>int<CODE> </CODE>-&gt;<CODE> </CODE>int<CODE> </CODE>-&gt;<CODE> </CODE>int<CODE> </CODE>-&gt;<CODE> </CODE>int<CODE> </CODE>-&gt;<CODE> </CODE>int<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"plus_bytecode"</CODE><CODE> </CODE><CODE>"plus_native"</CODE><CODE> </CODE>;;<BR>print_int<CODE> </CODE><TT>(</TT>plus<CODE> </CODE><CODE>1</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE><CODE>3</CODE><CODE> </CODE><CODE>4</CODE><CODE> </CODE><CODE>5</CODE><CODE> </CODE><CODE>6</CODE><TT>)</TT><CODE> </CODE>;;<BR>print_newline<CODE> </CODE>()<CODE> </CODE>;;<BR>

</PRE>
<BR>
<BR>
We now compile these programs with the two Objective CAML compilers and a C
compiler that we call <TT>cc</TT>. We must give it the access path for the
<TT>mlvalues.h</TT> include file.
<PRE>
$ cc -c -I/usr/local/lib/ocaml  exC.c 

$ ocamlc -custom exC.o exOCAML.ml -o ex_byte_code.exe 
$ ex_byte_code.exe
&lt;&lt; BYTECODED PLUS &gt;&gt; : 21 

$ ocamlopt exC.o exOCAML.ml -o ex_native.exe 
$ ex_native.exe 
&lt;&lt; NATIVE PLUS &gt;&gt; : 21 
</PRE>

<H3> Note </H3> <HR>

To avoid writing the C function twice (with the same body but
different calling conventions), it suffices to implement the bytecode
version as a call to the native-code version, as in the following sketch:<BR><TT>value prim_nat (value x1, ..., value xn) { ... }</TT><BR><TT>value prim_bc (value *tbl, int n)</TT><BR><TT>{ return prim_nat(tbl[0],tbl[1],...,tbl[n-1]) ; }</TT>


<HR>

<BR>
<BR>
<A NAME="toc149"></A>
<H3> Linking with C</H3>
<A NAME="@concepts258"></A>
The linking phase creates an executable from C and Objective CAML files
compiled with their respective compilers. The result of the
native-code compiler is shown in figure <A HREF="book-ora114.html#fig-com2-C">12.2</A>.<BR>
<BR>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<IMG SRC="book-ora043.gif">
</DIV>
<BR>
<DIV ALIGN=center>Figure 12.2: Mixed-language executable.</DIV><BR>

<A NAME="fig-com2-C"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>The compilation of the C and Objective CAML sources generates machine code
that is stored in the static allocation area of the program. The
dynamic allocation area contains the execution stack (corresponding to the
function calls in progress) and the heaps for C and Objective CAML.<BR>
<BR>

<H4> Run-time libraries</H4>
The C functions that can be called from a program using only the
standard Objective CAML library are contained in the execution library of
the abstract machine (see figure <A HREF="book-ora065.html#fig-zinc">7.3</A> page <A HREF="book-ora065.html#fig-zinc">??</A>). 
For such a program, there is no need to provide additional libraries
at link-time. However, when using Objective CAML libraries such as
<TT>Graphics</TT>, <TT>Num</TT> or <TT>Str</TT>, the programmer must
explicitly provide the corresponding C libraries at link-time.
This is the purpose of the <TT>-custom</TT> compiler option (see
<A HREF="index.html#chap-Compilation">7</A>, page&nbsp;<A HREF="book-ora067.html#sec-standalone">??</A>).
Similarly, when we wish to call our C functions from Objective CAML, we must
provide the object file containing those C functions at link-time.
The following example illustrates this.<BR>
<BR>

<H4> The three linking modes</H4>
The linking commands differ slightly between the native-code compiler,
the bytecode compiler, and the construction of toplevel interactive
loops. The compiler options relevant to these linking modes are
described in chapter <A HREF="index.html#chap-Compilation">7</A>.<BR>
<BR>
To illustrate these linking modes, we consider again the example in
figure <A HREF="book-ora114.html#fig-com1-C">12.1</A>. Assume the Objective CAML source file is named <TT>progocaml.ml</TT>. It uses the external function <TT>f_c</TT>
defined in the C file <TT>progC.c</TT>. In turn, the function
<TT>f_c</TT> refers to a C library <TT>a_C_library.a</TT>. Once all these files
are compiled separately, we link them together using the following commands:
<UL>
<LI>
 bytecode:<BR><CODE>ocamlc -custom -o vbc.exe progC.o a_C_library.a progocaml.cmo</CODE> 

<LI> native code:<BR><CODE>ocamlopt progC.o -o vn.exe a_C_library.a progocaml.cmx</CODE> 
</UL>
We obtain two executable files: <TT>vbc.exe</TT> for the bytecode version,
and <TT>vn.exe</TT> for the native-code version.<BR>
<BR>

<H4> Building an enriched abstract machine</H4>
Another possibility is to augment the run-time library of the abstract
machine with new C functions callable from Objective CAML. This is achieved
by the following commands:
<PRE>
ocamlc -make-runtime -o new_ocamlrun progC.o a_C_library.a
</PRE>We can then build a bytecode executable <TT>vbcnam.exe</TT> targeted to
the new abstract machine:
<PRE>
ocamlc -o vbcnam.exe -use-runtime new_ocamlrun progocaml.cmo
</PRE>To run this bytecode executable, either give it as the first argument
to the new abstract machine, as in <CODE>new_ocaml vbcnam.exe</CODE> , or
run it directly as <CODE>vbcnam.exe</CODE><BR>
<BR>


<H3> Note </H3> <HR>

Linking in <TT>-custom</TT> mode scans the object files (<TT>.cmo</TT>) to
build a table of all external functions mentioned. The bytecode
required to use them is generated and added to the bytecode
corresponding to the Objective CAML code.


<HR>

<BR>
<BR>

<H4> Building a toplevel interactive loop</H4>
To be able to use an external function in the toplevel interactive
loop, we must first build a new toplevel interpreter
containing the C code for the
function, as well as an Objective CAML file containing its declaration.<BR>
<BR>
We assume that we have compiled the file <TT>progC.c</TT> containing the function
<TT>f_c</TT>. We then build the toplevel loop <TT>ftop</TT> 
as follows:
<PRE>
ocamlmktop -custom -o ftop progC.o a_C_library.a ex.ml
</PRE>The file <TT>ex.ml</TT> contains the external declaration for the function
<TT>f</TT>. The new toplevel interpreter <TT>ftop</TT> then knows this function and
contains the corresponding C code, as found in <TT>progC.o</TT>.<BR>
<BR>
<A NAME="toc150"></A>
<H3> Mixing input-output in C and in Objective CAML</H3>
<A NAME="@concepts259"></A>
The input-output functions in C and in Objective CAML do not share their
file buffers. Consider the following C program:<BR>
<BR>


<PRE>
<CODE>#include &lt;stdio.h&gt;</CODE><BR><CODE>#include &lt;caml/mlvalues.h&gt;</CODE><BR><CODE>value hello_world (value v)</CODE><BR><CODE>  { printf("Hello World !!");  fflush(stdout);  return v; }</CODE><BR><BR>

</PRE>

Writes to standard output must be flushed explicitly (<TT>fflush</TT>) to
guarantee that they will be printed in the intended order.<BR>
<BR>


<PRE><BR># <B>external</B><CODE> </CODE>caml_hello_world<CODE> </CODE><CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE>unit<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"hello_world"</CODE><CODE> </CODE><CODE> </CODE>;;<BR><CODE>external caml_hello_world : unit -&gt; unit = "hello_world"</CODE><BR># print_string<CODE> </CODE><CODE>"&lt;&lt; "</CODE><CODE> </CODE>;<BR><CODE> </CODE>caml_hello_world<CODE> </CODE>()<CODE> </CODE>;<BR><CODE> </CODE>print_string<CODE> </CODE><CODE>" &gt;&gt;\n"</CODE><CODE> </CODE>;<BR><CODE> </CODE>flush<CODE> </CODE>stdout<CODE> </CODE>;;<BR><CODE>Hello World !!&lt;&lt;  &gt;&gt;</CODE><BR><CODE>- : unit = ()</CODE><BR>

</PRE>
<BR>
<BR>
The outputs from C and from Objective CAML are not intermingled as expected,
because each language buffers its outputs independently. To get the
correct behavior, the Objective CAML part must be rewritten as follows:


<PRE><BR># print_string<CODE> </CODE><CODE>"&lt;&lt; "</CODE><CODE> </CODE>;<CODE> </CODE>flush<CODE> </CODE>stdout<CODE> </CODE>;<BR><CODE> </CODE>caml_hello_world<CODE> </CODE>()<CODE> </CODE>;<CODE> </CODE><BR><CODE> </CODE>print_string<CODE> </CODE><CODE>" &gt;&gt;\n"</CODE><CODE> </CODE>;<CODE> </CODE>flush<CODE> </CODE>stdout<CODE> </CODE>;;<BR><CODE>&lt;&lt; Hello World !! &gt;&gt;</CODE><BR><CODE>- : unit = ()</CODE><BR>

</PRE>

By flushing the Objective CAML output buffer after each write, we ensure that
the outputs from each language appear in the expected order.<BR>
<BR>
<HR>
<A HREF="book-ora113.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora115.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
